package com.yowasa.xiuxian.service;

import com.google.common.collect.Maps;
import com.yowasa.xiuxian.constant.ApiPath;
import com.yowasa.xiuxian.constant.BotConfig;
import com.yowasa.xiuxian.entity.bot.Gateway;
import com.yowasa.xiuxian.entity.bot.channel.Channel;
import com.yowasa.xiuxian.entity.bot.channel.CreatDMSReq;
import com.yowasa.xiuxian.entity.bot.channel.DMS;
import com.yowasa.xiuxian.entity.bot.channel.Guild;
import com.yowasa.xiuxian.entity.bot.message.Message;
import com.yowasa.xiuxian.entity.bot.message.SendMessageReq;
import com.yowasa.xiuxian.entity.bot.user.User;
import com.yowasa.xiuxian.util.JSONUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.util.List;
import java.util.Map;
import java.util.Objects;

@Service
public class QQChannelService {
    @Autowired
    private BotConfig config;

    @Autowired
    private RestTemplate restTemplate;

    /**
     * 用于获取 WSS 接入地址，通过该地址可建立 websocket 长连接
     *
     * @return 返回一个用于连接 websocket 的地址
     */
    public Gateway gateway() {
        String url = config.getUrl(ApiPath.GET_GATEWAY);
        return restTemplate.getForObject(url, Gateway.class);
    }

    /**
     * 获取机器人用户信息
     *
     * @return
     */
    public User getBotInfo() {
        String url = config.getUrl(ApiPath.GET_BOT_INFO);
        return restTemplate.getForObject(url, User.class);
    }

    /**
     * 获取机器人加入的频道列表
     *
     * @return
     */
    public List<Guild> getBotGuilds() {
        String url = config.getUrl(ApiPath.GET_BOT_GUIDE);
        HttpHeaders headers = new HttpHeaders();
        Map<String, Object> parameters = Maps.newHashMap();
        parameters.put("limit", 100);
        HttpEntity<Map<String, String>> requestEntity = new HttpEntity(parameters, headers);
        ResponseEntity<List<Guild>> exchange = restTemplate.exchange(url, HttpMethod.GET, requestEntity, new ParameterizedTypeReference<List<Guild>>() {
        });
        return exchange.getBody();
    }

    /**
     * 依据频道id查询频道信息
     *
     * @param guildId
     * @return
     */
    public Guild getGuildInfo(String guildId) {
        String url = config.getUrl(ApiPath.GET_GUIDE_INFO, guildId);
        return restTemplate.getForObject(url, Guild.class);
    }

    /**
     * 获取机器人加入的频道列表
     *
     * @return
     */
    public List<Channel> getGuildChannel(String guildId) {
        String url = config.getUrl(ApiPath.GET_CHANNEL_LIST, guildId);
        HttpHeaders headers = new HttpHeaders();
        Map<String, Object> parameters = Maps.newHashMap();
        HttpEntity<Map<String, String>> requestEntity = new HttpEntity(parameters, headers);
        ResponseEntity<List<Channel>> exchange = restTemplate.exchange(url, HttpMethod.GET, requestEntity, new ParameterizedTypeReference<List<Channel>>() {
        });
        return exchange.getBody();
    }


    /**
     * 获取子频道详情
     *
     * @param channelId
     * @return
     */
    public Channel getChannelInfo(String channelId) {
        String url = config.getUrl(ApiPath.GET_CHANNEL_INFO, channelId);
        return restTemplate.getForObject(url, Channel.class);
    }


    /**
     * 创建子频道
     *
     * @param channel
     * @return
     */
    public Channel createChannel(Channel channel) {
        String url = config.getUrl(ApiPath.CREATE_CHANNEL, channel.getGuildId());
        ResponseEntity<Channel> responseEntity = restTemplate.postForEntity(url, channel, Channel.class);
        return responseEntity.getBody();
    }

    /**
     * 删除子频道（注:401没权限）
     *
     * @param channelId
     */
    public void deleteChannel(String channelId) {
        String url = config.getUrl(ApiPath.DELETE_CHANNEL, channelId);
        HttpHeaders headers = new HttpHeaders();
        Map<String, Object> parameters = Maps.newHashMap();
        HttpEntity<Map<String, String>> requestEntity = new HttpEntity(parameters, headers);
        restTemplate.delete(url);
    }

    /**
     * @param channelId 子频道id
     * @param userId    用户id
     * @param flag      true为新增 false为删除
     * @return
     */
    public void setPermission(String channelId, String userId, boolean flag) {
        String url = config.getUrl(ApiPath.SET_CHANNEL_PERMISSION, channelId, userId);
        HttpHeaders headers = new HttpHeaders();
        Map<String, Object> parameters = Maps.newHashMap();
        if (flag) {
            parameters.put("add", "1");
        } else {
            parameters.put("remove", "1");
        }
        HttpEntity<Map<String, String>> requestEntity = new HttpEntity(parameters, headers);
        restTemplate.exchange(url, HttpMethod.PUT, requestEntity, new ParameterizedTypeReference<Object>() {
        });
    }


    /**
     * 根据消息id和频道id获取消息
     *
     * @param channelId
     * @param messageId
     * @return
     */
    public Message getMessage(String channelId, String messageId) {
        String url = config.getUrl(ApiPath.GET_MESSAGE, channelId, messageId);
        return restTemplate.getForObject(url, Message.class);
    }


    private Message sendWithFile(String url, Map<String, Object> data) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        MultiValueMap<String, Object> parameters = new LinkedMultiValueMap<>();
        parameters.setAll(data);
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(parameters, headers);
        ResponseEntity<Message> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, Message.class);
        return response.getBody();
    }

    public Message originSend(String channelId, SendMessageReq data) {
        String url = config.getUrl(ApiPath.SEND_CHANNELS_MESSAGE, channelId);
        return restTemplate.postForObject(url, data, Message.class);
    }

    public Message originSendPrivate(String guildId, SendMessageReq data) {
        String url = config.getUrl(ApiPath.SEND_PRIVATE_MESSAGE, guildId);
        return restTemplate.postForObject(url, data, Message.class);
    }


    /**
     * 发送频道消息
     *
     * @param channelId
     * @param data
     * @return
     */
    public Message send(String channelId, SendMessageReq data) {
        Map map = JSONUtils.toObject(JSONUtils.toJson(data), Map.class);
        if (Objects.nonNull(data.getFileImage())) {
            map.put("file_image", data.getFileImage());
        }
        String url = config.getUrl(ApiPath.SEND_CHANNELS_MESSAGE, channelId);
        return sendWithFile(url, map);
    }

    /**
     * 创建私信频道
     *
     * @param data
     * @return
     */
    public DMS createPrivate(CreatDMSReq data) {
        String url = config.getUrl(ApiPath.CREATE_PRIVATE_MESSAGE);
        return restTemplate.postForObject(url, data, DMS.class);
    }

    /**
     * 发送私信消息
     *
     * @param data
     * @return
     */
    public Message sendPrivate(String guildId, SendMessageReq data) {
        Map map = JSONUtils.toObject(JSONUtils.toJson(data), Map.class);
        String url = config.getUrl(ApiPath.SEND_PRIVATE_MESSAGE, guildId);
        if (Objects.nonNull(data.getFileImage())) {
            map.put("file_image", data.getFileImage());
        }
        return sendWithFile(url, map);
    }


}
